package com.qys.livesMall.navy.service;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.qys.livesMall.app.user.model.entity.H2AppUserAddress;
import com.qys.livesMall.app.user.service.IH2AppUserAddressService;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.exception.enums.ExceptionEnum;
import com.qys.livesMall.common.message.MessageServer;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.finance.service.FinanceUserAccountService;
import com.qys.livesMall.navy.common.Constant;
import com.qys.livesMall.navy.model.dto.task.AddShopOrder;
import com.qys.livesMall.navy.model.entity.NavyTask;
import com.qys.livesMall.navy.model.entity.NavyTaskDetail;
import com.qys.livesMall.navy.task.TaskInter;
import com.qys.livesMall.shop.modal.dto.shop.order.NavyAddOrder;
import com.qys.livesMall.shop.modal.entity.*;
import com.qys.livesMall.shop.service.ShopGoodsSkuService;
import com.qys.livesMall.shop.service.api.impl.ShopOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @menu NavyShopOrderServer
 * @date 2023/07/11 18:09
 */
@Slf4j
@Service
public class NavyShopOrderServer {

    @Autowired
    private MessageServer messageServer;

    @Autowired
    private ShopGoodsSkuService shopGoodsSkuService;

    @Autowired
    private FinanceUserAccountService userBalanceService;

    @Autowired
    private IH2AppUserAddressService userAddressService;

    @Autowired
    private ShopOrderService shopOrderService;

    @Autowired
    private NavyTaskTX navyTaskTX;

    @Autowired
    private NavyTaskDetailService navyTaskDetailService;

    @Autowired
    private NavyTaskService navyTaskService;

    @Autowired
    private TaskInter taskInter;


    public R buildTask(AddShopOrder param){
        if (param==null|| CollectionUtils.isEmpty(param.getNavyIds())
                ||CollectionUtils.isEmpty(param.getShopIds())
        ||param.getType()==null){
            return messageServer.failMsg(ExceptionEnum.PARAM_IS_ERROR);
        }
        if (Objects.equals(param.getType(), Constants.Number.ZERO)){

        }else {

        }
        return R.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    public R moreShopOrder(AddShopOrder param){
        //创建任务
        NavyTask task=new NavyTask();
        task.setTaskType(Constant.TaskType.SHOP_ORDER);
        task.setTaskStatus(Constant.TaskStatus.RUNNING);
        task.setTaskParam(JSONObject.toJSONString(param));
        task.setTaskStartTime(LocalDateTime.now());
        task.setCreateDate(LocalDateTime.now());
        task.setAmount(param.getAmount());
        task.setTaskName("水军打单");
        //创建任务明细
        List<NavyTaskDetail> details = new ArrayList<>();
        if(!CollectionUtils.isEmpty(param.getShopIds())) {

            int sort=1;
            for (Long shopId:param.getShopIds()){
                NavyTaskDetail detail=new NavyTaskDetail();
                detail.setNavyIds(JSONObject.toJSONString(param.navyIds));
                detail.setTaskType(Constant.TaskType.SHOP_ORDER);
                detail.setShopIds(shopId.toString());
                detail.setTaskStatus(Constant.TaskDetailStatus.NO_START);
                detail.setSort(sort);
                detail.setShopGoodsIds(JSONObject.toJSONString(param.shopGoodsIds));
                detail.setAmount(param.getAmount());
                detail.setCreateDate(LocalDateTime.now());
                details.add(detail);
            }
        }
        //落库
        navyTaskTX.navyPlanOrder(task,details);
        //开启任务
        for(NavyTaskDetail detail:details){
            try {
                exc(detail.getId());
            }catch (Exception e){
                log.error("店铺下单执行错误："+e);
            }
        }
        return R.ok();
    }

    @Async
    public void exc(Long taskDetailId){
        NavyTaskDetail detail = navyTaskDetailService.getById(taskDetailId);
        if (detail==null){
            return;
        }
        List<Long> shopGoodsIds=JSONArray.parseArray(detail.getShopGoodsIds()).toJavaList(Long.class);
        if (CollectionUtils.isEmpty(shopGoodsIds)){
            shopGoodsIds=null;
        }
        //获取余额最大的水军余额
        List<Long> userIds=JSONArray.parseArray(detail.getNavyIds()).toJavaList(Long.class);
        userIds=userAddressService.getExistByUserIds(userIds);
        if (CollectionUtils.isEmpty(userIds)){
            detail.setTaskStatus(Constant.TaskDetailStatus.END_SUCCESS);
            detail.setRemark("所有水军:"+detail.getNavyIds()+"没有默认地址，结束任务！");
            navyTaskDetailService.upById(detail);
            nextTask(detail);
            return;
        }
        BigDecimal maxBalance=userBalanceService.maxBalanceByUserIds(userIds);
        //最大打单余额
        BigDecimal amount=detail.getAmount().compareTo(maxBalance)>0?maxBalance:detail.getAmount();
        //获取一个可用的sku
        ShopGoodsSku sku=shopGoodsSkuService.getSkuByGoods(shopGoodsIds,amount,Long.valueOf(detail.getShopIds()));
        if (sku==null){
            detail.setTaskStatus(Constant.TaskDetailStatus.END_SUCCESS);
            detail.setRemark("有地址的水军最大余额："+amount+",打单剩余余额："+detail.getAmount()+",找不到合适商品，结束任务！");
            navyTaskDetailService.upById(detail);
            nextTask(detail);
        }else {
            //取一个余额足够的水军
            List<String> userIdStr=userBalanceService.getSufficientAmountUser(sku.getPrice());
            if (CollectionUtils.isEmpty(userIdStr)){
                detail.setTaskStatus(Constant.TaskDetailStatus.END_SUCCESS);
                detail.setRemark("未找到足够金额:"+sku.getPrice()+" 的水军用户,结束任务！");
                navyTaskDetailService.upById(detail);
                nextTask(detail);
                return;
            }
            //取交集
            userIds.retainAll(userIdStr.stream().map(Long::valueOf).collect(Collectors.toList()));
            if (CollectionUtils.isEmpty(userIds)){
                detail.setTaskStatus(Constant.TaskDetailStatus.END_SUCCESS);
                detail.setRemark("未找到符合条件的水军用户"+JSONObject.toJSONString(userIds)+",结束任务！");
                navyTaskDetailService.upById(detail);
                nextTask(detail);
                return;
            }
            //构建下单信息
            //获取水军收件地址
            H2AppUserAddress address=userAddressService.getByUserIds(userIds);
            if (address==null){
                detail.setTaskStatus(Constant.TaskDetailStatus.END_SUCCESS);
                detail.setRemark("水军"+JSONObject.toJSONString(userIds)+"，没有默认地址,结束任务！");
                navyTaskDetailService.upById(detail);
                nextTask(detail);
                return;
            }
            NavyAddOrder orderInfo=new NavyAddOrder();
            orderInfo.setUserId(Long.valueOf(address.getUserId()));
            orderInfo.setSkuId(sku.getId());
            orderInfo.setNum(1);
            BeanUtils.copyProperties(address,orderInfo);
            orderInfo.setConsigUser(address.getUserName());
            ShopOrder order=shopOrderService.add(orderInfo);
            if (order.getOrderInfo()!=null){
                shopOrderService.pay(order.getOrderInfo().getId());
            }
            detail.setAmount(detail.getAmount().subtract(sku.getPrice()));
            navyTaskDetailService.upById(detail);
            nextTask(detail);
        }
    }

    private void nextTask(NavyTaskDetail detail){ //同步主任务状态
        boolean end=navyTaskService.watchTaskEnd(detail.getTaskId());
        if (end){
            return;
        }
        if (Objects.equals(detail.getTaskStatus(), Constant.TaskDetailStatus.NO_START)){
            taskInter.addShopOrderTask(RandomUtil.randomInt(600,5400),detail.getId());
        }

    }
}

